#ifndef ROMS_MENU_H_
#define ROMS_MENU_H_

#include "std_lib_facilities.h"
#include <map>
#include <iostream>
#include <string>
#include <stdexcept>
#include <vector>
#include <sstream> // FPW, B.3
//other types
#include "Category.h"
#include "Menu_Item.h"
#include "Recipe.h"
#include "Ingredient.h"
#include "Order.h"
#include "Order_Item.h"

using namespace std;

namespace ROMS{   
	
	enum Msg_type{
	Exit_program=1, About_info, About_help, Close_about_box,
	Read_recipes_ingredients, Read_orders, Read_category_menu_items,
	Show_order, Show_recipe, Show_menu,
	/* This folllowing code written by Fransiska Putri Wina to solve B.3 */
	Show_categories, Show_order_items,
	/* end of code by FPW, B.3 */
	Find_category_sales, Find_table_sales, Find_menu_item_sales,
	Update_add_order_item, Update_add_menu_item, Update_add_recipe,
	Graph_order_sales,Graph_table_sales,Graph_category_sales,
	Tables_button, Orders_button, Categories_button, Recipes_button, Menu_items_button,
	Display_window, Menu_bar_cb,
	find_table_sales_button, //SBH C
	find_menu_item_button, //FPW, C - find sales for menu item
	update_recipe_button //FPW, C - update recipe

	};
   
	struct InvalidType : std::runtime_error {
	  InvalidType(): runtime_error("Invalid type data") {}
	};

class ROMS_Menu {
public:
   struct InvalidData : std::runtime_error {
      InvalidData(): runtime_error("Invalid input data format") {}
   };

   struct InvalidFile : std::runtime_error {
      InvalidFile(): runtime_error("Invalid input file name") {}
   };

   enum Main_menu_options{ Info=1, Read, Show, Find, Update, Exit }; 

   enum Rec_type{ Cats=1, Menu_entry, Rec, Ingred, Ord, Ord_item };

   enum File_type{	Tbls=Tables_button, 
					CatMI=Categories_button, 
					Prds=Menu_items_button, 
					Carts=Orders_button, 
					Items=Recipes_button }; 
		
	ROMS_Menu();
   
   void display_main_menu() const;
   void display_info() const;//display assignment info & your name plus "Project Part I"
   void read();		 
   void update();
   int update_recipe(string,string); //FPW, C - 3 update recipe
   void show() const;
   double find(int find_num, string parameter); //FPW, C - find sales for menu item
   void read_recipes_ingredients(string);
   void Read_orders(string);
   void read_catprds(string);
   void save();
   //AJN C
   void add_order_item(String,int,int,int);
   //AJN C category sales in prep for extra credit
   int get_first_year();
   int get_last_year();
   double category_sales(string);
   double category_sales(Category);
   double category_sales(Category,int,int,int,int);
   bool in_category(Order_Item item,Category cat);
   bool in_date_range(Order_Item item,int start_year,int start_month,int end_year,int end_month);
   double get_price(Order_Item);
   Menu_Item get_menu_by_order(Order_Item item);
   string catsales();
   Order get_order(Order_Item item);
   //AJN D
   vector<double> get_month_order_sales();
   map<int,double> get_table_sales();
   //FPW - D 3
   int get_menu_item_cat_id (int menu_item_id) ;
   vector<vector<double> > ROMS_Menu::get_categories_sales();
   

   //SBH C
   void add_menu_item(int , int , int , string , double , Description );
   
   
   
   	
   //show functions added to support GUI interface
   string show_button(Msg_type);
   /* This following code written by Fransiska Putri Wina to solve B.3 */
   string show_menu_bar(Msg_type);
   /* end of code by FPW, B.3 */

	template <typename T>
	string show_func(T t, string s)
	{
		string r;
		if(0==t.size())
			r = "No "+s+" Data Loaded\n";
		else
			for(int i=0; i<t.size(); ++i)
			{
				r+=t[i].display();
				r+="\n";
			}
		return r;
	}

	/* These following code written by Fransiska Putri Wina to solve B.3 */
	string show_func_categories() {
		int n_menu_item; //number of menu items in the following category
		string r;
		if(0==categories.size())
			r = "No Category Data Loaded\n";
		else
			for(int i=0; i<categories.size(); ++i) {
				n_menu_item = 0;
				r+=categories[i].display();
				r+="\n";
				for (int j=0; j<menu_items.size(); ++j) {
					if (menu_items[j].get_cat_id() == categories[i].get_id()) {
						++n_menu_item;
						if (n_menu_item == 1) {
							r+="Menu Items in "+categories[i].get_name()+":\n";
						}
						r+="\t"+menu_items[j].display();
						r+="\n";
					}
				} 

				if (n_menu_item == 0) {
					r+="There is no Menu Item in "+categories[i].get_name()+"\n\n";
				}
				else {
					r+="\n";
				}
			}
		return r;
	}

	string show_func_order_item() {
		int n_order_item; //number of menu items in the following category
		string r;
		char buffer[5];
		if(0==order_items.size())
			r = "No Order Items Data Loaded\n";
		else
			for(int i=0; i<orders.size(); ++i) {
				n_order_item = 0;
				r+="Order Information: "+orders[i].display();
				r+="\n";
				for (int j=0; j<order_items.size(); ++j) {
					if (order_items[j].get_order_id() == orders[i].get_order_id()) {
						++n_order_item;
						if (n_order_item == 1) {
							//typecasting integer to string
							string s;
							stringstream out;
							out << orders[i].get_order_id();
							s = out.str();

							r += "Order Items in "+ s +":\n";
						}
						r+="\t"+order_items[j].display();
						r+="\n";
					}
				} 

				if (n_order_item == 0) {
					//typecasting integer to string
					string s;
					stringstream out;
					out << orders[i].get_order_id();
					s = out.str();

					r += "There is no Order Item in "+ s +"\n\n";
				}
				else {
					r+="\n";
				}
			}
		return r;
	}
	/* end of code by FPW, B.3 */
private:
   //private data
	vector<Category> categories;
	vector<Menu_Item> menu_items;
	vector<Recipe> recipes;
	vector<Ingredient> ingredients;
	vector<Order> orders;
	vector<Order_Item> order_items;


	int get_file_info(ifstream& ist, string prompt, string fname);	//A.1,2,3 merge added a function for common code
	void read_file(ifstream& file, int num_rec, Rec_type ftype);
	string get_long_string(ifstream& ist);
};
} //end namespace ROMS

#endif //ROMS_MENU_H_
